package br.com.virtual.cadastrar.dao.impl;

import java.util.List;

import javax.persistence.NoResultException;

import br.com.virtual.base.dao.impl.BaseDaoImpl;
import br.com.virtual.cadastrar.dao.PessoaDAO;
import br.com.virtual.cadastrar.model.Pessoa;
import br.com.virtual.cadastrar.model.Produto;

public class PessoaDAOImpl extends BaseDaoImpl implements PessoaDAO {

	@Override
	public Pessoa findByEmail(String email) {

		Pessoa pessoa = null;
		try {
			pessoa = (Pessoa) getManager()
					.createQuery(
							" select p from Pessoa p where p.email = :email ",
							Pessoa.class).setParameter("email", email)
					.getSingleResult();
		} catch (Exception e) {
		}

		return pessoa;
	}

	@Override
	public Pessoa read(Long id) {

		return this.getManager().find(Pessoa.class, id);
	}

	@Override
	public List<Pessoa> list() {

		return this.getManager()
				.createQuery("select pes from Pessoa pes", Pessoa.class)
				.getResultList();
	}
	
	
	@Override
	public List<Pessoa> listToShow(){
		
		StringBuilder sql = new StringBuilder();
		
		sql.append("select new " + Pessoa.class.getName());
		sql.append(" (pes.id, pes.nome, pes.telefone1, pes.email, pes.usuario, pes.tipoPessoa)");
		sql.append(" from Pessoa pes");
		sql.append(" order by pes.id desc");
		
		return getManager().createQuery(sql.toString(), Pessoa.class).getResultList();
		
	}
	

	@Override
	public void delete(Pessoa pessoa) {
		this.getManager().remove(read(pessoa.getId()));
	}

	@Override
	public List<String> getEmailListToNews() {

		StringBuffer buffer = new StringBuffer("select new ");
		buffer.append(String.class.getName());
		buffer.append("(p.email)");
		buffer.append("from Pessoa p where p.newsLetter = true");

		List<String> emails = this.getManager()
				.createQuery(buffer.toString(), String.class).getResultList();
		return emails;
	}

	@Override
	public Pessoa loadAvaliacao(Pessoa pessoa) {

		StringBuffer buffer = new StringBuffer();
		
		buffer.append(" select p from Pessoa p");
		buffer.append(" left join fetch p.avaliacoes a");
		buffer.append(" where p = :pessoa");

		
		try{
			return this.getManager().createQuery(buffer.toString(), Pessoa.class)
					.setParameter("pessoa", pessoa)
					.getSingleResult();
		}catch(NoResultException e){
			return null;
		}
	}

	@Override
	public List<Pessoa> getCandidatosASemelhante(List<Produto> produtosAvaliados) {

		StringBuffer buffer = new StringBuffer();
		
		buffer.append(" select distinct pes from Pessoa pes ");
		buffer.append(" left join fetch pes.avaliacoes ava ");
		buffer.append(" where pes in ( ");
		buffer.append(" select p from Pessoa p");
		buffer.append(" left join p.avaliacoes a");
		buffer.append(" where a.produto in (:produtos)");
		buffer.append(" )");
		
		return this.getManager().createQuery(buffer.toString(), Pessoa.class)
				.setParameter("produtos", produtosAvaliados)
				.getResultList();
	}

}
